
/*
 * Copyright (C) 2008-2009 Archie L. Cobbs. All rights reserved.
 *
 * $Id: AbstractSchemaUpdate.java 377 2010-03-11 20:50:18Z archie.cobbs $
 */

package org.dellroad.sidekar.schema.change;

import org.dellroad.sidekar.schema.SchemaModificationException;
import org.dellroad.sidekar.schema.model.EntityModel;
import org.dellroad.sidekar.schema.model.IndexModel;
import org.dellroad.sidekar.schema.model.SchemaModel;

/**
 * {@link SchemaChange} that removes a field from some entity in the schema.
 */
public class RemoveFieldChange extends FieldChange {

    /**
     * Constructor.
     *
     * @param entityName name of the entity from which the field should be removed
     * @param fieldName name of the field to be removed
     * @throws IllegalArgumentException if {@code entityName} is not a legal entity name
     * @throws IllegalArgumentException if {@code fieldName} is not a legal field name
     */
    public RemoveFieldChange(String entityName, String fieldName) {
        super(entityName, fieldName);
    }

    @Override
    public String getDescription() {
        return "remove field `" + this.getFieldName() + "' from entity `" + this.getEntityName() + "'";
    }

    @Override
    public void checkValidFor(SchemaModel schemaModel) {
        super.checkValidFor(schemaModel);
        final EntityModel entityModel = this.checkEntityExists(schemaModel, this.getEntityName());
        this.checkFieldExists(entityModel, this.getFieldName());

        // Verify no there are no indexes associated with the field in any descendants
        for (EntityModel otherEntityModel : schemaModel.getEntityModels().values()) {
            if (entityModel.isAncestorOf(otherEntityModel)) {
                for (IndexModel indexModel : otherEntityModel.getIndexModels().values()) {
                    for (String fieldName : indexModel.getFieldNames()) {
                        if (fieldName.equals(this.getFieldName())) {
                            throw new SchemaModificationException("can't remove field `" + fieldName + "' from " + entityModel
                              + " because it is indexed by index `" + indexModel.getName() + "' of "
                              + this.getDescription(otherEntityModel, entityModel));
                        }
                    }
                }
            }
        }
    }

    @Override
    public final void visit(SchemaChangeSwitch schemaChangeSwitch) {
        schemaChangeSwitch.caseRemoveFieldChange(this);
    }
}

